package com.strawcom.charmring.ui;

import android.annotation.SuppressLint;
import android.content.*;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.Toast;
import com.strawcom.charmring.BaseActivity;
import com.strawcom.charmring.C;
import com.strawcom.charmring.R;
import com.strawcom.charmring.bluetooth.RingBleService;
import com.strawcom.charmring.bluetooth.RingBleService.LocalBinder;
import com.strawcom.charmring.imagebrowser.AlbumActivity;
import com.strawcom.charmring.imagebrowser.ImageBean;
import com.strawcom.charmring.imagebrowser.ShowImageActivity;
import com.strawcom.charmring.util.*;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 
 * @ClassName: CameraActivity
 * @Description:拍照activity
 * @author liyongqiang
 * @date 2015-4-6 下午10:22:59
 * 
 */
@SuppressLint("SimpleDateFormat") public class CameraActivity extends BaseActivity implements OnClickListener, SurfaceHolder.Callback {

	private static final String TAG = CameraActivity.class.getSimpleName();
	private static final int MEDIA_TYPE_IMAGE = 1;
	private View switchCamera;
	private SurfaceView surfaceSv;
	private View layoutCapture;
	private SurfaceHolder mHolder;
	private Camera mCamera;
	// 0表示后置，1表示前置
	private int cameraPosition = 1;
	private View layoutMyalbum;
	private boolean isTorch = true; //闪光默认打开
	private ImageView imgTorch;
	private View layoutTorch;
	private static final int msg_close_torch = 1;
	private static final int msg_auto_focus = 2;
	private View layoutBack;

	private String currRingAddress;
	private RingBleService bleService;

	private View layoutPreview;
	private ImageView imgPerview;
	private View layoutFocus;
	
	private int mCameraWidth;

	@Override protected void onCreate(Bundle savedInstanceState) {
		setContentView(R.layout.activity_camrea);
		super.onCreate(savedInstanceState);

		switchCamera =  this.findViewById(R.id.layout_rotating);
		layoutCapture = this.findViewById(R.id.layout_capture);
		surfaceSv = (SurfaceView) this.findViewById(R.id.sView);
		layoutMyalbum = findViewById(R.id.layout_myalbum);
		layoutTorch =  findViewById(R.id.layout_torch);
		layoutBack = findViewById(R.id.layout_back);
		layoutFocus = findViewById(R.id.layout_focus);
		switchCamera.setOnClickListener(this);
		layoutCapture.setOnClickListener(this);
		layoutMyalbum.setOnClickListener(this);
		layoutTorch.setOnClickListener(this);
		surfaceSv.setOnClickListener(this);
		layoutBack.setOnClickListener(this);
		layoutFocus.setOnClickListener(this);

		layoutPreview = findViewById(R.id.layout_preview);
		
		imgPerview = (ImageView) findViewById(R.id.img_preview);
		imgTorch = (ImageView) findViewById(R.id.img_torch_);

		mHolder = surfaceSv.getHolder();
		mHolder.setKeepScreenOn(true);// 屏幕常亮  
		mHolder.addCallback(this);
		
		String lastPerview = PreferenceUtil.readString(this, C.sp.camera_perview);
		if(!TextUtils.isEmpty(lastPerview)) {
			Bitmap bm = BitmapFactory.decodeFile(lastPerview);
			showPerViewByAnim(bm);
		}
		
		mCameraWidth = ScreenUtil.getScreenWidth(this);

		bindRingBleService();
		registerRingMessageReceiver();
	}

	private void showPerViewByAnim(Bitmap bm) {
		imgPerview.setVisibility(View.VISIBLE);
		imgPerview.clearAnimation();
		imgPerview.setImageBitmap(bm);
		imgPerview.startAnimation(AnimUtil
				.init()
				.addAlpha(0.1f, 1f)
				.addScale(0.1f, 1f, 0.1f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, 0, 300,
						new OvershootInterpolator()).create());
		layoutPreview.setOnClickListener(new OnClickListener() {
			@Override public void onClick(View v) {
				showPerview();
			}
		});
	}

	@Override public void onResume() {
		super.onResume();
		if (this.checkCameraHardware(this) && (mCamera == null)) {
			// 打开camera
			try {
				mCamera = Camera.open();
				// 打开聚焦
				Camera.Parameters params = mCamera.getParameters();
				params.setPictureFormat(ImageFormat.JPEG);
				params.setJpegQuality(100);
				params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
				
				Size pictureS = CameraParamUtil.getInstance().getPictureSize(params.getSupportedPictureSizes(), mCameraWidth); 
				params.setPictureSize(pictureS.width, pictureS.height);  
				Size previewS = CameraParamUtil.getInstance().getPreviewSize(params.getSupportedPreviewSizes(), mCameraWidth); 
				params.setPreviewSize(previewS.width, previewS.height);
				
				mCamera.setParameters(params);
				// 通过surfaceview显示取景画面
				mCamera.setDisplayOrientation(90);
				
				if (mHolder != null) setStartPreview(mCamera, mHolder);
				// mCamera.cancelAutoFocus();
				mCamera.autoFocus(null);
				cameraPosition = 1;
			} catch (Exception e) {
				// Camera is not available (in use or does not exist)
				mCamera = null;
				Log.e(TAG, "Camera is not available (in use or does not exist)");
			}
		}
		handler.sendEmptyMessageDelayed(msg_auto_focus,1500);
	}

	@Override public void onPause() {
		super.onPause();
		/**
		 * 记得释放camera，方便其他应用调用
		 */
		releaseCamera();
		
		handler.removeMessages(msg_auto_focus);
	}

	@Override public void onDestroy() {
		super.onDestroy();
		/**
		 * 记得释放camera，方便其他应用调用
		 */
		releaseCamera();

		handler.removeMessages(msg_close_torch);

		if (!TextUtils.isEmpty(currRingAddress)) {
			bleService.requestMotionThreshold(currRingAddress, false);
		}
		bleService.setThresholdOverflowOnCamera(false);

		unbindRingBleService();
		unregisterRingMessageReceiver();
	}

	/**
	 * 释放mCamera
	 */
	private void releaseCamera() {
		if (mCamera != null) {
			mCamera.setPreviewCallback(null);
			mCamera.stopPreview();// 停掉原来摄像头的预览
			mCamera.release();
			mCamera = null;
		}
	}

	@Override public void onClick(View v) {
		switch (v.getId()) {
		case R.id.layout_rotating:
			// 切换前后摄像头
			int cameraCount = 0;
			CameraInfo cameraInfo = new CameraInfo();
			cameraCount = Camera.getNumberOfCameras();// 得到摄像头的个数

			for (int i = 0; i < cameraCount; i++) {
				Camera.getCameraInfo(i, cameraInfo);// 得到每一个摄像头的信息
				if (cameraPosition == 1) {
					// 现在是后置，变更为前置
					if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
						/**
						 * 记得释放camera，方便其他应用调用
						 */
						releaseCamera();
						// 打开当前选中的摄像头
						mCamera = Camera.open(i);
						Camera.Parameters params = mCamera.getParameters();
						params.setPictureFormat(ImageFormat.JPEG);
						params.setJpegQuality(100);
						params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
						
						Size pictureS = CameraParamUtil.getInstance().getPictureSize(params.getSupportedPictureSizes(), mCameraWidth); 
						params.setPictureSize(pictureS.width, pictureS.height);  
						Size previewS = CameraParamUtil.getInstance().getPreviewSize(params.getSupportedPreviewSizes(), mCameraWidth); 
						params.setPreviewSize(previewS.width, previewS.height);
						
						mCamera.setParameters(params);
						// 通过surfaceview显示取景画面
						mCamera.setDisplayOrientation(90);
						setStartPreview(mCamera, mHolder);
						// mCamera.cancelAutoFocus();
						mCamera.autoFocus(null);
						cameraPosition = 0;
						break;
					}
				}
				else {
					// 现在是前置， 变更为后置
					if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
						/**
						 * 记得释放camera，方便其他应用调用
						 */
						releaseCamera();
						mCamera = Camera.open(i);
						Camera.Parameters params = mCamera.getParameters();
						params.setPictureFormat(ImageFormat.JPEG);
						params.setJpegQuality(100);
						params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
						
						Size pictureS = CameraParamUtil.getInstance().getPictureSize(params.getSupportedPictureSizes(), mCameraWidth); 
						params.setPictureSize(pictureS.width, pictureS.height);  
						Size previewS = CameraParamUtil.getInstance().getPreviewSize(params.getSupportedPreviewSizes(), mCameraWidth); 
						params.setPreviewSize(previewS.width, previewS.height);
						
						mCamera.setParameters(params);
						mCamera.setDisplayOrientation(90);
						
						setStartPreview(mCamera, mHolder);
						// mCamera.cancelAutoFocus();
						mCamera.autoFocus(null);
						cameraPosition = 1;
						break;
					}
				}

			}

			switchCamera.clearAnimation();
			switchCamera.startAnimation(AnimUtil.init().addAlpha(1f, 0.1f, 0, 200, null, Animation.REVERSE).create());
			break;
		case R.id.layout_capture:
			if(isTorch) {
				//拍摄时候闪光
				if (mCamera != null) {
					Camera.Parameters parameters = mCamera.getParameters();
					parameters.setFlashMode(isTorch?Parameters.FLASH_MODE_TORCH:Parameters.FLASH_MODE_OFF);
					mCamera.setParameters(parameters);
				}
				handler.sendEmptyMessageDelayed(msg_close_torch, 800);
			}
			if (mCamera != null) {
				mCamera.takePicture(null, null, pictureCallback);

				layoutCapture.clearAnimation();
				layoutCapture.startAnimation(AnimUtil
						.init().addAlpha(1f,0f, 0, 400, new LinearInterpolator(), Animation.REVERSE).create()
						);
			}
			break;
		case R.id.layout_myalbum:
			startActivity(new Intent(this, AlbumActivity.class));
			break;
		case R.id.layout_torch:
			isTorch = !isTorch;
			imgTorch.setImageResource(isTorch?R.drawable.lightning:R.drawable.unlightning);
			
			imgTorch.clearAnimation();
			imgTorch.startAnimation(AnimUtil.init().addAlpha(1f, 0.1f, 0, 200, null, Animation.REVERSE).create());
			break;
		case R.id.sView:
			break;
		case R.id.layout_back:
			onBackPressed();
			break;
		case R.id.layout_focus:
			if(mCamera!= null) {
//				mCamera.cancelAutoFocus();
				mCamera.autoFocus(null);
			}
			layoutFocus.startAnimation(AnimUtil.init().addAlpha(1f, 0.1f, 0, 200, null, Animation.REVERSE).create());
			break;
		}
	}

	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case msg_close_torch:
				if (mCamera != null) {
					Camera.Parameters parameters = mCamera.getParameters();
					parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
					mCamera.setParameters(parameters);
				}
				break;
			case msg_auto_focus:
				if(mCamera != null) {
					try {
						mCamera.autoFocus(null);
						handler.sendEmptyMessageDelayed(msg_auto_focus, 5000);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				break;
			}
		};
	};

	@Override public void surfaceCreated(SurfaceHolder holder) {

		setStartPreview(mCamera, mHolder);
	}

	@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		// If your preview can change or rotate, take care of those events here.
		// Make sure to stop the preview before resizing or reformatting it.

		if (mHolder.getSurface() == null) {
			// preview surface does not exist
			return;
		}

		// stop preview before making changes
		try {
			mCamera.stopPreview();
		} catch (Exception e) {
			// ignore: tried to stop a non-existent preview
		}
		// set preview size and make any resize, rotate or
		// reformatting changes here

		// start preview with new settings
		setStartPreview(mCamera, mHolder);
	}

	@Override public void surfaceDestroyed(SurfaceHolder holder) {
		// 当surfaceview关闭时，关闭预览并释放资源
		/**
		 * 记得释放camera，方便其他应用调用
		 */
		releaseCamera();
		holder = null;
		surfaceSv = null;
	}

	/**
	 * 创建png图片回调数据对象
	 */
	PictureCallback pictureCallback = new PictureCallback() {
		@Override public void onPictureTaken(byte[] data, Camera camera) {
			final File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
			if (pictureFile == null) {
				Log.d(TAG, "Error creating media file, check storage permissions: ");
				return;
			}

			Bitmap bm0 = BitmapFactory.decodeByteArray(data, 0, data.length);
			Matrix m = new Matrix();

			if (cameraPosition == 0) { // 后置
				m.setRotate(270, (float) bm0.getWidth() / 2, (float) bm0.getHeight() / 2);
				m.postScale(-1, 1); // 水平翻转
			}
			else if (cameraPosition == 1) { // 前置
				m.setRotate(90, (float) bm0.getWidth() / 2, (float) bm0.getHeight() / 2);
			}

			final Bitmap bm = Bitmap.createBitmap(bm0, 0, 0, bm0.getWidth(), bm0.getHeight(), m, true);

			new Thread(new Runnable() {
				@Override public void run() {
					ImageUtil.saveBitmap2file(bm, pictureFile.getAbsolutePath());
					PreferenceUtil.write(CameraActivity.this, C.sp.camera_perview, pictureFile.getAbsolutePath());
					fileScan(pictureFile.getAbsolutePath());
					
					runOnUiThread(new Runnable() {
						public void run() {
							showPerViewByAnim(bm); // 显示预览图
						}
					});
				}
			}).start();

			returnResult(pictureFile);

		}
	};

	public void fileScan(String fName) {
		Uri data = Uri.parse("file://" + fName);
		sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, data));
	}

	/**
	 * Create a File for saving an image or video
	 */
	private static File getOutputMediaFile(int type) {

		// File mediaStorageDir = new
		// File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),"MyCameraApp");
		File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), C.app.album_name);
		// This location works best if you want the created images to be shared
		// between applications and persist after your app has been uninstalled.

		// Create the storage directory if it does not exist
		if (!mediaStorageDir.exists()) {
			if (!mediaStorageDir.mkdirs()) {
				Log.d("MyCameraApp", "failed to create directory");
				return null;
			}
		}

		// Create a media file name
		String timeStamp = getDateFormatString(new Date());
		File mediaFile;
		if (type == MEDIA_TYPE_IMAGE) {
			mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".png");
		}
		else {
			return null;
		}
		return mediaFile;
	}

	public static String getDateFormatString(Date date) {
		if (date == null) date = new Date();
		SimpleDateFormat matter = new SimpleDateFormat("yyyyMMdd_HHmmss");
		String formatStr = new String();
		formatStr = matter.format(date);
		return formatStr;
	}

	/** Check if this device has a camera */
	private boolean checkCameraHardware(Context context) {
		if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
			// this device has a camera
			return true;
		}
		else {
			// no camera on this device
			return false;
		}
	}

	/**
	 * activity返回式返回拍照图片路径
	 * 
	 * @param mediaFile
	 */
	private void returnResult(File mediaFile) {
		// Intent intent = new Intent();
		// intent.setData(Uri.fromFile(mediaFile));
		Toast.makeText(this, R.string.photo_save_info, Toast.LENGTH_SHORT).show();
		mCamera.stopPreview();
		setStartPreview(mCamera, mHolder);
	}

	/**
	 * 设置camera显示取景画面,并预览
	 * 
	 * @param camera
	 */
	private void setStartPreview(Camera camera, SurfaceHolder holder) {
		try {
			camera.setDisplayOrientation(90);
			camera.setPreviewDisplay(holder);
			camera.startPreview();
		} catch (Exception e) {
			Log.d(TAG, "Error starting camera preview: " + e.getMessage());
		}
	}

	private void bindRingBleService() {
		Intent intent = new Intent(this, RingBleService.class);
		bindService(intent, conn, BIND_AUTO_CREATE);
	}

	private void unbindRingBleService() {
		unbindService(conn);
	}

	private final ServiceConnection conn = new ServiceConnection() {
		@Override public void onServiceDisconnected(ComponentName name) {
			LogUtil.e("CameraActivity onServiceDisconnected()");
			bleService = null;
		}

		@Override public void onServiceConnected(ComponentName name, IBinder service) {
			LogUtil.e("CameraActivity onServiceConnected()");
			bleService = ((LocalBinder) service).getService();
			currRingAddress = bleService.getCurrAddress();
			if (!TextUtils.isEmpty(currRingAddress)) {
				bleService.requestMotionThreshold(currRingAddress, true);
			}

			bleService.setThresholdOverflowOnCamera(true);
		}
	};

	private void registerRingMessageReceiver() {
		IntentFilter filter = new IntentFilter();
		filter.addAction(RingBleService.ACTION_GATT_MOTION_THRESHOLD_OVERFLOW);
		registerReceiver(ringMessageReceiver, filter);
	}

	private void unregisterRingMessageReceiver() {
		unregisterReceiver(ringMessageReceiver);
	}

	private final BroadcastReceiver ringMessageReceiver = new BroadcastReceiver() {
		@Override public void onReceive(Context context, Intent intent) {
			final String action = intent.getAction();
			if (RingBleService.ACTION_GATT_MOTION_THRESHOLD_OVERFLOW.equals(action)) {
				LogUtil.e("晃动去拍照");

				long lastCaptureTime = PreferenceUtil.readLong(CameraActivity.this, C.sp.camera_capture_last_time);
				if (System.currentTimeMillis() - lastCaptureTime < 3000) {
					// 
					LogUtil.e("过滤短时间内的 [晃动去拍照] 消息");
					return;
				}
				PreferenceUtil.write(CameraActivity.this, C.sp.camera_capture_last_time, System.currentTimeMillis());

				findViewById(R.id.layout_capture).performClick();
			}
		}
	};

	/**
	 * 利用ContentProvider扫描手机中的图片，此方法在运行在子线程中
	 */
	private void showPerview() {
		if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
			Toast.makeText(this, R.string.no_sd_card, Toast.LENGTH_SHORT).show();
			return;
		}

		new Thread(new Runnable() {
			@Override public void run() {
				HashMap<String, List<String>> mGruopMap = new HashMap<String, List<String>>();
				Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
				ContentResolver mContentResolver = getContentResolver();
				// 只查询jpeg和png的图片
				Cursor mCursor = mContentResolver.query(mImageUri, null, MediaStore.Images.Media.MIME_TYPE + "=? or "
						+ MediaStore.Images.Media.MIME_TYPE + "=?", new String[] { "image/jpeg", "image/png" },
						MediaStore.Images.Media.DATE_MODIFIED);
				while (mCursor.moveToNext()) {
					// 获取图片的路径
					String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));
					// 获取该图片的父路径名
					String parentName = new File(path).getParentFile().getName();
					// 根据父路径名将图片放入到mGruopMap中
					if (!mGruopMap.containsKey(parentName)) {
						List<String> chileList = new ArrayList<String>();
						chileList.add(path);
						mGruopMap.put(parentName, chileList);
					}
					else {
						mGruopMap.get(parentName).add(path);
					}
				}
				mCursor.close();

				List<ImageBean> list = subGroupOfImage(mGruopMap);
				List<String> childList = mGruopMap.get(list.get(0).getFolderName());
				
				Intent intent=new Intent(CameraActivity.this,ShowImageActivity.class);
				intent.putStringArrayListExtra("list", (ArrayList<String>)childList);
				intent.putExtra("poistion", childList.size()-1);
				startActivity(intent);
				
			}
		}).start();
	}

	/**
	 * 组装分组界面GridView的数据源，因为我们扫描手机的时候将图片信息放在HashMap中 所以需要遍历HashMap将数据组装成List
	 * 
	 * @param mGruopMap
	 * @return
	 */
	private List<ImageBean> subGroupOfImage(HashMap<String, List<String>> mGruopMap) {
		if (mGruopMap.size() == 0) {
			return null;
		}
		List<ImageBean> list = new ArrayList<ImageBean>();

		ImageBean mRingAblum = new ImageBean();
		list.add(mRingAblum);

		Iterator<Map.Entry<String, List<String>>> it = mGruopMap.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry<String, List<String>> entry = it.next();
			String key = entry.getKey();
			List<String> value = entry.getValue();

			if (C.app.album_name.equals(key)) {
				// 将自己的相册放在第一位
				mRingAblum.setFolderName(key);
				mRingAblum.setImageCounts(value.size());
				mRingAblum.setTopImagePath(value.get(value.size() - 1));// 获取该组的最后一张图片
			}
			else {
				ImageBean mImageBean = new ImageBean();
				mImageBean.setFolderName(key);
				mImageBean.setImageCounts(value.size());
				mImageBean.setTopImagePath(value.get(value.size() - 1));// 获取该组的第最后一张图片
				list.add(mImageBean);
			}
		}

		return list;
	}
}
